<?php
// +----------------------------------------------------------------------
// | Ntalker插件安装程序 For UCHome                                                             
// +----------------------------------------------------------------------
// | Copyright (c) 2010 http://www.ntalker.comt All rights reserved.      
// +----------------------------------------------------------------------
// | Author: lsh 
// | Latest Update:    2010-10-08                          
// +----------------------------------------------------------------------
if(!defined('IN_NTALKER')) {
    exit('Access Denied');
}
/**
 +------------------------------------------------------------------------
 * 获取GET/POST值
 +------------------------------------------------------------------------
 * @param string	$keys	变量名
 * @param string	$method	获取方式
 +------------------------------------------------------------------------
 */
function InitGP($keys,$method=null){
	!is_array($keys) && $keys = array($keys);
	foreach ($keys as $value) {
		$GLOBALS[$value] = NULL;
		if ($method!='P' && isset($_GET[$value])) {
			$GLOBALS[$value] = trim($_GET[$value]);
		} elseif ($method!='G' && isset($_POST[$value])) {
			$GLOBALS[$value] = trim($_POST[$value]);
		}
	}
}
/**
 +------------------------------------------------------------------------
 * 查找论坛目录
+------------------------------------------------------------------------
 * @param string    $checkdir    待检查目录
 * @param string    $lenth    待检查目录和安装目录的路径差值
 * @param string    $type    true：安装检查；false：卸载检查
 +------------------------------------------------------------------------
 */
 function check_bbsdir($checkdir='',$lenth=0,$type=true){
      if(!$checkdir && $lenth==0){
           $type && $lenth = strlen(dirname(__FILE__)) - strrpos(str_replace("\\","/",dirname(__FILE__)),'/');
           $checkdir = substr(INSTALLROOT, 0, strrpos(str_replace('\\','/',INSTALLROOT), '/') + 1-$lenth);
      }
      if(file_exists($checkdir.'./config.php')){
           define('Uchome_ROOT', $checkdir);
           return $lenth;
      }elseif(strlen($checkdir)<=strlen(SITEROOT)){
            //只检查到网站根目录
            return -1;
      }else{
           $lenth = strlen(str_replace('\\','/',INSTALLROOT))-strlen(str_replace('\\','/',dirname($checkdir)));
           $checkdir = substr(INSTALLROOT, 0, strrpos(str_replace('\\','/',INSTALLROOT), '/') + 1-$lenth).'/';
           return check_bbsdir($checkdir,$lenth);
      } 
 }
/**
 +------------------------------------------------------------------------
 * 获取模板信息
 +------------------------------------------------------------------------
 */
function templateinfo(){
     $folder = array();
     $_folder = opendir(Uchome_ROOT.'./template');
     while(($file = readdir($_folder)) !== false)  {
     	  if($file!='.' && $file!='..'){
               $folder[] = $file;
          }
     }
     closedir($_folder);
     return $folder;
}
/**
 +------------------------------------------------------------------------
 * 检测是否安装 
 +------------------------------------------------------------------------
 */
function checkInstall(){
      global $clsreg,$insfilelist;
      $_count = 0;
      $allFileList = loadfilelist();
      foreach($allFileList as $key=> $arr) {
           if(!$arr['tpl']){
                $_count += getrecount($arr['file'], $clsreg['code']);
           }else{
                $_count += getrecount($arr['file'], $clsreg['tpl']);
           }
      }
      return $_count ? true : false;
}

/**
 +------------------------------------------------------------------------
 * 检查文件中是否有ntalker代码 
 +------------------------------------------------------------------------
 * @param string    $filepath    文件路径
 * @param string    $_reg        判断ntalker代码的正则表达式
 +------------------------------------------------------------------------
 */    
function getrecount($filepath, $_reg){
     $_count = 0;
     $_fileCon = file_get_contents(Uchome_ROOT.$filepath);
     foreach($_reg as $rg){
          $_count += preg_match_all($rg, $_fileCon, $matches);
     }
     return $_count;
}
/**
 +------------------------------------------------------------------------
 * 所有待修改文件列表
 +------------------------------------------------------------------------
 * @param array    $tpl    指定要修改的模板路径
 +------------------------------------------------------------------------
 */
function loadFileList($tpl=''){
     global $insfilelist;
     !$tpl && $tpl = templateinfo();
     foreach($tpl AS $tpldir){
     	  $_tempdir = './template/'.$tpldir;
          foreach($insfilelist['clsconfig'] as $file=> $cfg){
               $all_file = $cfg['tpl'] ? $_tempdir.'/'.$file : "./$file";
               if(file_exists(Uchome_ROOT.$all_file) && ($cfg['tpl'] || (!$cfg['tpl'] && $tpldir=='default'))){
                    $filelist[] = array(
                         'key'  => $file,
                         'tpl'  => $cfg['tpl'],
                         'must' => $cfg['must'],
                         'file' => $all_file,
                         'tempdir' => $cfg['tpl'] ? $_tempdir : '',
                         'styname'  => INSCHARSET=="utf-8" ? $tpldir : siconv($tpldir,'UTF-8',INSCHARSET),
                    );
               }
          }
     }
     return $filelist;
}
/**
 +------------------------------------------------------------------------
 * 判断是否安装锁定 
 +------------------------------------------------------------------------
 */
function inschecklock(){
      if(file_exists(INSTALLROOT.'install.lock')){
            return true;
      }else{
            return false; 
      }
}
/**
 +------------------------------------------------------------------------
 * 判断论坛版本是否支持
 +------------------------------------------------------------------------
 * @param string    $filename    配置文件路径和名字
 +------------------------------------------------------------------------
 */
function inscheckversion($filename){
     if(file_exists(INSTALLROOT.$filename)){
           return true;
     }else{
           return false;   
     }
}
/**
 +------------------------------------------------------------------------
 * 判断安装所需权限设置
 +------------------------------------------------------------------------
 * @param bool    $ins  install:安装检查，reinstall:重新安装检查,  uninstall:卸载检查
 * @param bool    $tplid  模板id 
 +------------------------------------------------------------------------
 */
function inscheckperm($ins='install',$tplid=''){
     global $insfilelist,$insauthkey,$clsreg; 
     $_msg = $tids = $_desc = '';
     $allFileList = loadfilelist($tids);
     $files = array();
     foreach($allFileList as $key=>$arr) {
          $files[$key] = Uchome_ROOT.$arr['file'];
          if($arr['key']=='header.htm'){
              $tpkey = $arr['tempdir'];
              $files[$tpkey] = Uchome_ROOT.$tpkey;
              //卸载时，检查ntalkertoolbar.htm的权限
              if($ins!='install'){
              	  if(file_exists(Uchome_ROOT.$tpkey.'/ntalkertoolbar.htm')){
              	  		 $htmkey = $arr['tempdir'].'htm';
                  		 $files[$htmkey] = Uchome_ROOT.$tpkey.'/ntalkertoolbar.htm';
              	  }
                  //兼容老版本footer.htm卸载
                  $oldtplfile = str_replace('header.htm','footer.htm',$arr['file']);
                  if(getrecount($oldtplfile, $clsreg['tpl'])>0 && !isset($files[$oldtplfile])){
                       $files[$oldtplfile] = Uchome_ROOT.$oldtplfile;
                  }  
              }
          }
     }
     //检查网站目录是否有crossdomain.xml，如果有，则检查其权限，否则不再检查网站根目录权限
     if(ck_crossdomain(true)){
          $files['crossdomain'] = SITEROOT.'./crossdomain.xml';
     }
     //如果安装目录为论坛目录，则不检查论坛目录权限
     if(defined("NTALKER_DATA_ROOT")){
          $files['ins'] = Uchome_ROOT.'./install/index.php';
          $files['unins'] = Uchome_ROOT.'./uninstall.php';
     }else{
          $files['ins'] = rtrim(Uchome_ROOT.SHOW_INS_ROOT,'/');
     }
     $files['bak'] = Uchome_ROOT.SHOW_INS_ROOT.'bak';
     $files['data'] = Uchome_ROOT.SHOW_INS_ROOT.'ntalkerdata';
     if($ins!='install'){
         $nfiles = array('imxml.php','imconfig.inc.php');
         foreach($nfiles as $nfile){
              if(file_exists(INSTALLROOT.$nfile)){
                   $files[$nfile] = Uchome_ROOT.SHOW_INS_ROOT.$nfile;
              }
              //兼容老版本ntalker文件卸载
              if(file_exists(Uchome_ROOT.$nfile)){
                   $key = 'old'.$nfile;
                   $files[$key] = Uchome_ROOT.'./'.$nfile;
              }
         }
         //兼容老版本程序文件卸载
         $oldfile = './common.php';
         if(getrecount($oldfile, $clsreg['code'])>0 && !in_array(Uchome_ROOT.$oldfile,$files)){
         	  $files[$oldfile] = Uchome_ROOT.$oldfile;
         }
     }
     //检查是否存在当前版本文件 和 当前版本配置文件
     $ins_file_baks = array(
                            'verfile'=>'ntalker_version.php',
                            'confile'=>'ntalkerdata/config_'.X_VER.'.php',
                            );
     foreach($ins_file_baks as $key=>$ins_file_bak){
          if(file_exists(INSTALLROOT.'ntalkerdata/'.$ins_file_bak)){
               $files[$key] = Uchome_ROOT.SHOW_INS_ROOT.'ntalkerdata/'.$ins_file_bak;
          }
     }
     if($ins=='uninstall'){
          $imageurl = 'install/images/';
     }else{
          $imageurl = 'images/';
     }
     $check_ok = true;
     foreach($files as $key=>$file){
            //便于显示，只显示相对于论坛的路径，检查论坛根目录时，不替换。2010-06-13修改
            $filename = str_replace(Uchome_ROOT,'',$file);
            if(!$filename){
            	 $filename = $file;
            }
            echo '<tr>';
            echo '<td height="30">'.$filename.'</td>';
            echo '<td><img src="'.$imageurl.'ok.gif" width="16" height="14" />　可写</td>';  
            if(is_dir($file)){
                if(!insdirwriteable($file)){
                     echo '<td><img src="'.$imageurl.'no.gif" width="14" height="14" />　不可写</td>';
                     $check_ok = false; 
                }else{
                     echo '<td><img src="'.$imageurl.'ok.gif" width="16" height="14" />　可写</td>';
                }
            }else{
                  if(file_exists($file)){
                       @chmod($file,0777);
                       if(!is_writable($file)){
                            echo '<td><img src="'.$imageurl.'no.gif" width="14" height="14" />　不可写</td>';
                            $check_ok = false;
                       }else{
                            $fp = @fopen($file,'ab');
                            if($fp===false){
                                 echo '<td><img src="'.$imageurl.'no.gif" width="14" height="14" />　不可写</td>';
                                 $check_ok = false;
                            }else{
                                 echo '<td><img src="'.$imageurl.'ok.gif" width="16" height="14" />　可写</td>';
                                 fclose($fp);
                            }
                       }
                  }
            }
            echo '</tr>';
     }
     return  $check_ok;
}
/**
 +------------------------------------------------------------------------
 * 格式化消息提示
 +------------------------------------------------------------------------
 * @param bool    $complete 是否结论性消息
 * @param string  $_msg     消息内容
 * @param bool    $showmsg  是否显示消息内容
 +------------------------------------------------------------------------
 */
function message($complete, $_msg='', $showmsg=true){
     if($complete === true ){
          if($_msg != '' && $showmsg) 
               echo $_msg."<br />\n";
          return true;
     }elseif($complete===false ){
          if($_msg != '' && $showmsg)
               echo '<font color="red">'.$_msg."</font><br />\n";
          return true;
     }else{
           if($_msg != '' && $showmsg)
               echo $_msg."<br />\n";
           return false;
     }
}
/**
 +------------------------------------------------------------------------
 * 判断目录是否可写
 +------------------------------------------------------------------------
 * @param string  $dir     目录的路径
 +------------------------------------------------------------------------
 */
function insdirwriteable($dir) {
     $isw = 0;
     if($fp = @fopen("$dir/test.txt", 'w')) {
         @fclose($fp);
         @unlink("$dir/test.txt");
         $isw = 1;
     } 
     return $isw;
}
/**
 +------------------------------------------------------------------------
 * 列出所有模板
 +------------------------------------------------------------------------
 */
function templatelist(){

}
/**
 +------------------------------------------------------------------------
 * 安装ntalker
 +------------------------------------------------------------------------
 * @param int       $tplid              模版ID
 * @param int       $type               安装类型, 0:全新安装 1:重新安装  2010-08-21
 * @param string    $im_siteid          ntalker网站注册的ID 
 * @param int       $im_enablesitekey   是否是可以sitekey 
 * @param string    $im_sitekey         与ntalker通信的公共密钥
 +------------------------------------------------------------------------
 */
function Install($tplid='', $type=0, $im_siteid='', $im_enablesitekey=0, $im_sitekey=''){
     global $insdb,$insfilelist,$clsreg,$installSQL,$pluginCfg,$crossdomain;
     //此数组中的值将会替换原值存入插件数据表中
     $cfg__install = array('im_siteid'=>$im_siteid, 'im_enablesitekey'=>$im_enablesitekey, 'im_sitekey'=>$im_sitekey);
     //已安装过此插件
     if(checkInstall() && $type==0){
          exit ('<script>window.location.href=\''.SELF_FILE.'?action=installed\';</script>');
     }elseif(checkInstall() && $type==1){
          //重新安装，先执行卸载
          if(!uninstall(1)){
               return false;
          }
     }
     $tplinfo = loadFileList();
     //备份文件
     backupfiles($tplinfo);
     
     //复制imxml.php文件 、复制imconfig.inc.php文件
     $insfiles = array('imxml.php','imconfig.inc.php');
     foreach($insfiles as $insfile){
          if(file_exists(INSTALLROOT.'./install/'.INSCHARSET.'/'.X_VER.'_'.$insfile)){
               $copyfile = INSTALLROOT.'./install/'.INSCHARSET.'/'.X_VER.'_'.$insfile;
          }elseif(file_exists(INSTALLROOT.'./install/'.INSCHARSET.'/'.$insfile)){
               $copyfile = INSTALLROOT.'./install/'.INSCHARSET.'/'.$insfile;
          }
          if(defined("NTALKER_DATA_ROOT")){
               $destfile = NTALKER_DATA_ROOT.$insfile;
          }else{
               $destfile = INSTALLROOT.$insfile;
          }
          if(@copy($copyfile, $destfile)){
               @chmod($destfile,0777);
               message(true, "复制文件 $insfile ...成功");
               if($insfile=='imxml.php'){
                    if(!im_modify_root($destfile,0)){
                         message(false, "更新文件 $insfile ...失败，请将ntalker文件夹移动到论坛目录再安装！");
                         if($type){
                              echo '<input type="hidden" name="reinstallmsg" value="'.$insfile.':modify failed" />';
                         }else{
                              echo '<input type="hidden" name="installmsg" value="'.$insfile.':modify failed" />';
                         }
                         return false;
                    }
               }else{
                    im_modify_root($destfile,1);
               }
          }else{
               if($type){
               	    message(false, "复制文件 $insfile ...失败，请修改：".SHOW_INS_ROOT.$insfile." 有可写权限，再重新安装");
                    echo '<input type="hidden" name="reinstallmsg" value="'.$insfile.':copy failed" />';
               }else{
               	    message(false, "复制文件 $insfile ...失败，请修改：".SHOW_INS_ROOT." 有可写权限，再重新安装");
                    echo '<input type="hidden" name="installmsg" value="'.$insfile.':copy failed" />';
               }
               uninstall(2);
               return false;
          }
     } 
     
     //更新模版文件
     if(!updatefiles($tplinfo, $type)){
         //如果必须修改的文件修改失败，则执行卸载 
         uninstall(2);
         return false;
     }

     //验证并建立crossdomain.xml文件
     echo "<span class=\"title\">更新crossdomain.xml ... </span>";
     if(ck_crossdomain()){
          message( true, ' 成功');
     }elseif(!$type){
          message( true, ' 失败，请手动上传该文件至ucenter所在网站服务器的根目录！');
     }
     
     //清理模板缓存
     echo "<span class=\"title\">更新缓存...</span>&nbsp;&nbsp;";
     $tpl = dir(Uchome_ROOT.'./data/tpl_cache');
     while(false!==($entry = $tpl->read())) {
          @unlink(Uchome_ROOT.'./data/tpl_cache/'.$entry);
     }
     $tpl->close();
     message( true, ' 成功');

     //生成当前安装版本的版本信息文件，以及为卸载备份的版本配置文件到ntalkerdata文件夹
     @copy(INSTALLROOT.'./install/imbuild.php',INSTALLROOT.'./ntalkerdata/ntalker_version.php');
     @chmod(INSTALLROOT.'./ntalkerdata/ntalker_version.php',0777);
     @copy(INSTALLROOT.'./install/'.INSCHARSET.'./config_'.X_VER.'.php',INSTALLROOT.'./ntalkerdata/config_'.X_VER.'.php');
     @chmod(INSTALLROOT.'./config_'.X_VER.'.php',0777);
     
     //避免有些服务器不允许php程序同组可写，安装之后将imxml.php权限修改为755
     defined("NTALKER_DATA_ROOT") ? @chmod(NTALKER_DATA_ROOT.'imxml.php',0755) : @chmod(INSTALLROOT.'imxml.php',0755);        

     message( true, 'Ntalker文件修改完成!<br>');
     return true;
}
/**
 +------------------------------------------------------------------------
 * 原文件备份或者安装失败恢复原文件
 +------------------------------------------------------------------------
 * @param int       $tplinfo        备份模板 
 * @param bool      $ins           安装或者卸载备份文件
 +------------------------------------------------------------------------
 */
function backupfiles($tplinfo,$ins=true){
     global $insfilelist,$insdb,$insauthkey;
     $_backupdir = $ins ? INSTALLROOT.'./bak/install_bak' : INSTALLROOT.'./bak/uninstall_bak';
     $insday = date('Ymd',time());
     !is_dir($_backupdir) && @mkdir($_backupdir, 0777);
     !is_dir($_backupdir.'/'.$insday) && @mkdir($_backupdir.'/'.$insday, 0777);
     $bakdirs = array();
     !$tplinfo && $tplinfo = loadFileList();
     foreach($tplinfo as $tpl){
          $file = Uchome_ROOT.$tpl['file'];
          if($tpl['tempdir']){
               list($temdir0,$temdir1,$temdir2) = explode('/',$tpl['tempdir']);
               !is_dir($_backupdir.'/'.$insday.'/'.$temdir1) && @mkdir($_backupdir.'/'.$insday.'/'.$temdir1, 0777);
               !is_dir($_backupdir.'/'.$insday.'/'.$temdir1.'/'.$temdir2) && @mkdir($_backupdir.'/'.$insday.'/'.$temdir1.'/'.$temdir2, 0777);
               $bakfile = $tpl['tpl'] ? $_backupdir.'/'.$insday.'/'.$temdir1.'/'.$temdir2.'/'.basename($tpl['file']) : $_backupdir.'/'.$insday.'/'.basename($tpl['file']);
          }else{
               $bakfile = $_backupdir.'/'.$insday.'/'.basename($tpl['file']);
          }   
          //备份文件是否存在
          if(!file_exists($bakfile)){
               if(file_exists($file)){
                    @copy($file, $bakfile);                     
               }
          }
     }
}
/**
 +------------------------------------------------------------------------
 * 修改论坛程序或者模板文件
 +------------------------------------------------------------------------
 * @param int       $tplinfo      模版路径数组
 * @param int       $type        安装类型, 0:安装/1:重新安装
 +------------------------------------------------------------------------
 */
function updatefiles($tplinfo, $type=0){
     global $insdb,$insfilelist,$clsreg;
     $i = 0;
     $tplinfo = $tplinfo ? $tplinfo : loadFileList();
     foreach($tplinfo as $tpl){
          $__onerrnext = $tpl['styname']=='default' ? false : true; //非默认模板，忽略错误
          foreach($insfilelist['clsconfig'] as $key=>$val){
               //修改模板文件
               if($val['tpl']){
                    //是否必须修改文件
                    if($val['must']){
                         if(!updatefile($tpl['tempdir'], $key, !$__onerrnext, $type)){
                              return false;
                         }
                         $i++;
                    }else{
                          updatefile($tpl['tempdir'], $key, false, $type);
                    }
               }else{
                    //程序文件只更新一次
                    if(!$__onerrnext){
                         //是否必须修改文件
                         if($val['must']){
                              if(!updatefile($tpl['tempdir'], $key, true, $type)){
                                   return false;
                              }
                              $i++;
                         } 
                    }
               }
           }
     }
     //必须修改文件的操作数为0，返回false
     if($i>0){
          return true;
     }else{
          return false;
     }
}
/**
 +------------------------------------------------------------------------
 * 更新文件内容
 +------------------------------------------------------------------------
 * @param    string  $filename    模板路径
 * @param    string  $key         文件名称
 * @param    bool    $errnext     忽略错误
 * @param    int     $type        安装类型, 0:全新安装 1:修复安装  2010-8-21
 +------------------------------------------------------------------------
 */
function updatefile($filedir, $key, $errnext=false, $type=0){
     global $insdb,$insfilelist,$clsreg;
     $filename = Uchome_ROOT.$filedir.'/'.$key;
     if(!file_exists($filename)){          
          if($errnext){
               message(false, '更新文件 '.$filedir.'/'.$key.' ...不存在');
               return false;
          }else{
               return true;
          }  
     }else{
          //复制ntalker模板文件 
          if($key=='header.htm' && X_VER=='2.0'){
               if(!@copy(INSTALLROOT.'./install/'.INSCHARSET.'/'.X_VER.'_ntalkertoolbar.htm',Uchome_ROOT.$filedir.'/ntalkertoolbar.htm')){
                   if($type==0 || ($type==1 && INSTALL_VERSION_NEW!='equal')){
                        message( false, '复制文件 ntalkertoolbar.htm ...失败，请删除文件：'.$filedir.'/common/ntalkertoolbar.htm 再重新安装！');
                        if($type){
                             echo '<input type="hidden" name="reinstallmsg" value="ntalkertoolbar:copy failed" />';
                        }else{
                             echo '<input type="hidden" name="installmsg" value="ntalkertoolbar:copy failed" />';
                        }
                        return false;
                   } 
               }
               @chmod(Uchome_ROOT.$filedir.'/ntalkertoolbar.htm',0777);
          }
          $filecontent = file_get_contents($filename);
          $isbefore = $insfilelist['clsconfig'][$key]['isbefore'];
          $location = $insfilelist['clsconfig'][$key]['location'];
          $addcode = $insfilelist['clsconfig'][$key]['addcode']; 
          $newcode;
          $_file = $filedir.'/'.$key;
          //判断是否已经有Ntalker代码，如果已有代码，判断是否全新安装或者重新安装、版本不一致
          if($filedir && preg_match($clsreg['tpl'][0], $filecontent, $matches)>0 ){
               if($type==1 && INSTALL_VERSION_NEW!='equal') {
                    $filecontent = preg_replace($clsreg['tpl'][0], '', $filecontent);
               }else{
                    return true;
               }
          }elseif(!$filedir && preg_match($clsreg['code'][0], $filecontent, $matches)>0){
               if($type==1 && INSTALL_VERSION_NEW!='equal') {
                    $filecontent = preg_replace($clsreg['code'][0], '', $filecontent);
               }else{
                    return true;
               }
          }
          //单页面多标记 
          if(is_array($location)){ 
               foreach($location as $_k=>$_v){
                    $_location = $location[$_k];
                    $_addcode = trim($addcode[$_k]);
                    $_isbefore = $isbefore[$_k];
                    //查找标记
                    if(preg_match($_location, $filecontent, $matches)==0){
                         if($errnext){
                              message( false, '更新文件 '.$_file.' ...失败，默认标记代码不存在');
                              if($type){
                                   echo '<input type="hidden" name="reinstallmsg" value="'.$key.':marker absence" />';
                              }else{
                                   echo '<input type="hidden" name="installmsg" value="'.$key.':marker absence" />';
                              }
                              return false;
                         }else{
                              return true;
                         }
                    }
                    $newcode = $_isbefore ? $_addcode."\n".$matches[0]."\n" : $matches[0]."\n".$_addcode."\n"; 
                    //替换标记
                    $filecontent = preg_replace($_location, $newcode, $filecontent);
               }
          }elseif($location){
               if(preg_match($location, $filecontent, $matches)==0 ){
                    if($errnext){
                         message(false, '更新文件 '.$_file.' ...失败，默认标记代码不存在');
                         if($type){
                              echo '<input type="hidden" name="reinstallmsg" value="'.$key.':marker absence" />';
                         }else{
                              echo '<input type="hidden" name="installmsg" value="'.$key.':marker absence" />';
                         }
                         return false;
                    }else{
                         return true;
                    }
               }  
               $newcode = $isbefore ? trim($addcode)."\n".$matches[0]."\n" : $matches[0]."\n".trim($addcode)."\n"; 
               //替换标记
               $filecontent = preg_replace($location,$newcode,$filecontent);
          }else{
          		return true;
          }
          //非标准路径情况下，header.htm替换imconfig.inc.php的路径
          if($key=='header.htm'){
               if(!defined("NTALKER_DATA_ROOT") && SHOW_INS_ROOT=='./ntalker/'){
                    //默认情况下，不修改 
               }else{
                    if(defined("NTALKER_DATA_ROOT") && file_exists(Uchome_ROOT.'./data/ntalker/imconfig.inc.php')){
                         $filecontent = preg_replace('/ntalker\//i',"data/ntalker/",$filecontent);
                         //拷贝loader_ntalker.js到data/ntalker
                         @copy(INSTALLROOT.'./loader_ntalker.js',DISCUZ_BBS_ROOT.'/data/ntalker/loader_ntalker.js');
                    }else{
                         $sub_dir = substr(SHOW_INS_SITEURL, 0, 1) == '/' ? ltrim(SHOW_INS_SITEURL,'/') : SHOW_INS_SITEURL;
                         $sub_dir = substr(SHOW_INS_SITEURL, -1, 1) == '/' ? $sub_dir : $sub_dir.'/'; 
                         $filecontent = preg_replace('/ntalker\//i',$sub_dir,$filecontent);
                    }
               }
          }
          if(!$fp=@fopen($filename,"wb") ){
               if($errnext){
                    message(false, '更新文件 '.$_file.' ...失败，文件安装打开出错!如果在php.ini中配置了opendir，请修改配置；如果使用了php安全模式，请开启safe_mode_gid');
                    if($type){
                         echo '<input type="hidden" name="reinstallmsg" value="'.$key.':open failed" />';
                    }else{
                         echo '<input type="hidden" name="installmsg" value="'.$key.':open failed" />';
                    }
                    return false;
               }else{
                    return true;
               }
          } 
          if(@fwrite($fp, $filecontent) ){
               message(true, '更新文件 '.$_file.' ...成功');
          }else{
               if($errnext){
                    message(false, '更新文件 '.$_file.' ...失败，文件安装写入出错!请检查文件是否有可写权限！');
                    if($type){
                         echo '<input type="hidden" name="reinstallmsg" value="'.$key.':write failed" />';
                    }else{
                         echo '<input type="hidden" name="installmsg" value="'.$key.':write failed" />';
                    }
                    return false;
               }else{
                    return true;
               }
          }
          if($fp)fclose($fp);
          return true;
    }
}

/**
 +------------------------------------------------------------------------
 * 验证crossdomain文件
 +------------------------------------------------------------------------
 * @param    string  $ischeck     true：只检查是否需要修改；false：检查并修改
 +------------------------------------------------------------------------
 */
function ck_crossdomain($ischeck=false){
     global $crossdomain;
     $newcode;
     $allcode = $crossdomain['crossdomain.xml']['allcode'];
     $location = $crossdomain['crossdomain.xml']['location'];
     $addcode = trim($crossdomain['crossdomain.xml']['addcode']);
     $pcode = $crossdomain['crossdomain.xml']['pcode'];
     $filename = SITEROOT.'crossdomain.xml';
     $modify = true;
     if(file_exists($filename)){
           $fcon = file_get_contents($filename);
           foreach($pcode as $key=> $val){
                  //验证是否需要修改
                  if(preg_match($val, $fcon, $matches) > 0){
                        $modify = false;
                  }
           }
           if($modify && !$ischeck){
                if(preg_match($location, $fcon, $matches) <=0 ){//查找标记
                     return false;
                }
                $newcode = $addcode."\n".$matches[0];
                if(!$filecontent = preg_replace($location,$newcode,$fcon)){ //替换标记
                    return false;
                }
                if(!$handel=@fopen($filename,'wb')){
                    return false;
                }
                if(!@fwrite($handel, $filecontent)){        //写入文件
                    return false;
                }
                if($handel) fclose($handel);
           }elseif(!$modify && $ischeck){
                return false;    //不需要检查crossdomain.xml
           }
     }else{
           if(!$ischeck){
                //新建crossdomain文件
                if(!@copy(INSTALLROOT.'crossdomain.xml', $filename)){
                     return false;
                }
           }else{
                 return false;   //不需要检查crossdomain.xml
           }
     }
     return true; 
}
/**
 +------------------------------------------------------------------------
 * 卸载Ntalker
 +------------------------------------------------------------------------
 * @param    string  $uninstalltype  0:卸载； 1：重新安装前卸载 2：安装失败回滚 
 +------------------------------------------------------------------------
 */
function uninstall($uninstalltype=0) {
     global $insdb,$insfilelist,$clsreg,$insauthkey;
     if(!checkInstall() && $uninstalltype!=2){
          exit ('<script>window.location.href=\''.SELF_FILE.'\';</script>');
     }
     $tplinfo = loadFileList();    
     //卸载前备份文件
     backupfiles($tplinfo,false);
     
     if($uninstalltype){
          echo "<span class=\"title\">正在卸载已安装版本Ntalker ...</span><br />"; 
     }else{
          echo "<span class=\"title\">开始卸载Ntalker ...</span><br />";
     }
    
     foreach($tplinfo as $tpl){
          //程序代码只卸载一次
          $clearcode = $tpl['styname']=='default' ? true : false;
          //兼容老版本程序文件卸载
          if(!isset($insfilelist['clsconfig']['common.php']) && $clearcode){
         	  $insfilelist['clsconfig']['common.php']['tpl'] = false;
          }
          //兼容老版本footer.htm卸载
          if(!isset($insfilelist['clsconfig']['footer.htm'])){
         	     $insfilelist['clsconfig']['footer.htm']['tpl'] = true;
          }
          foreach($insfilelist['clsconfig'] as $key=>$val){
               $filename = $val['tpl'] ? $tpl['tempdir'].'/'.$key : './'.$key;
               //执行卸载代码操作
               if(!clear_file_code($filename,$val['tpl'],$clearcode)){
                    if($val['must']){
                         message(false, '卸载文件 '.$filename.' ...失败，请手工清除Ntalker代码！（for ntalker……begin和for ntalker……end之间的代码）');
                         if($uninstalltype){
                              echo '<input type="hidden" name="reinstallmsg" value="'.$key.':reinstll clear failed" />';
                         }else{
                              echo '<input type="hidden" name="uninstallmsg" value="'.$key.':uninstall failed" />';
                         }
                         return false;
                    }else{
                         message(false, '卸载文件 '.$filename.' ...失败，请手工清除Ntalker代码！（for ntalker……begin和for ntalker……end之间的代码）');
                    }
               }else{
                    if($key=='header.htm' && file_exists(Uchome_ROOT.$tpl['tempdir'].'/ntalkertoolbar.htm')){
                         if(!@unlink(Uchome_ROOT.$tpl['tempdir'].'/ntalkertoolbar.htm')){
                              message(false, '删除文件 ntalkertoolbar.htm ...失败，请手工删除：'.$tpl['tempdir'].'/ntalkertoolbar.htm');
                         }
                    }               
               }
          }
     }
     
     //删除接口文件和参数配置文件
     $filenames = array('imxml.php','imconfig.inc.php');
     foreach($filenames as $filename){
          if(defined("NTALKER_DATA_ROOT")){
               $srcfile = NTALKER_DATA_ROOT.$filename;
          }else{
               $srcfile = INSTALLROOT.$filename; 
          }
          if(file_exists($srcfile)){
               if(@unlink($srcfile)){
                    !$uninstalltype && message(true, '删除文件 '.$filename.' ...成功');
               }else{
                    message(false, '删除文件 '.$filename.' ...失败，请手工删除:'.$srcfile);
               }
          }
          //兼容老版本文件卸载
          if(file_exists(Uchome_ROOT.$filename)){
               @unlink(Uchome_ROOT.$filename);
          }
          //卸载loader_ntalker.js
          if(file_exists(NTALKER_DATA_ROOT.'loader_ntalker.js')){
               if(!@unlink(NTALKER_DATA_ROOT.'loader_ntalker.js')){
                    message(false, '删除文件 loader_ntalker.js ...失败，请手工删除:'.NTALKER_DATA_ROOT.'loader_ntalker.js');
               }
          }
     }
     
     //删除安装时备份的、版本文件和安装配置文件
     $ins_filenames = array('ntalker_version.php','config_'.X_VER.'.php');
     foreach($ins_filenames as $ins_filename){
          @unlink(INSTALLROOT.'./ntalkerdata/'.$ins_filename);
     }

     //清理模板缓存
     $tpl = dir(Uchome_ROOT.'./data/tpl_cache');
     while(false!==($entry = $tpl->read())) {
          @unlink(Uchome_ROOT.'./data/tpl_cache/'.$entry);
     }
     $tpl->close();
     !$uninstalltype && message(true, '清除缓存文件 ...完成.');
     message( true, 'Ntalker卸载完成!<br>');

     if(!$uninstalltype){
          if(defined("NTALKER_DATA_ROOT")){
               @unlink(Uchome_ROOT.'./install/index.php');
               @unlink(Uchome_ROOT.'./uninstall.php');
          }else{
               @touch(INSTALLROOT.'install.lock');
          }
     }
     return true;
}
/**
 +------------------------------------------------------------------------
 * 清理文件中的Ntalker代码
 +------------------------------------------------------------------------
 * @param    string  $file          文件名
 * @param    bool    $istpl         是否模板文件 
 * @param    bool    $clearcode     是否清理程序文件
 +------------------------------------------------------------------------
 */
function clear_file_code($file,$istpl,$clearcode){
     global $clsreg;
     //程序文件只清理一次
     if(!$clearcode && !$istpl){
           return true;
     }
     $filename = Uchome_ROOT.$file;
     if(file_exists($filename)){
          $filecontent = file_get_contents($filename);
          $cleared = false;
          if($istpl){
               foreach($clsreg['tpl'] as $reg){
                    $reg = trim($reg);
                    if(preg_match($reg,$filecontent,$match)>0){
                         $filecontent = preg_replace($reg, '', $filecontent);
                         $cleared = true;
                    }
               }
          }else{
                foreach($clsreg['code'] as $reg){
                    $reg = trim($reg);
                    if(preg_match($reg,$filecontent,$match)>0){
                         $filecontent = preg_replace($reg, '', $filecontent);
                         $cleared = true;
                    }
               }
          }
          if($cleared){
               if(!$fp=@fopen($filename, "wb")){
                     message(false, '卸载文件 '.$file.' ...失败，文件卸载打开出错!如果在php.ini中配置了opendir，请修改配置；如果使用了php安全模式，请开启safe_mode_gid');
                     echo '<input type="hidden" name="uninstallmsg" value="'.$file.':uninstall open failed" />';
                     return false;
               }
               if(!@fwrite($fp, $filecontent)){
                     message(false, '卸载文件 '.$file.' ...失败，文件卸载写入出错，请检查文件是否有可写权限!');
                     echo '<input type="hidden" name="uninstallmsg" value="'.$file.':uninstall write failed" />';
                     return false;
               }else{
                     message(true, '卸载文件 '.$file.' ...成功');
               }
               if($fp)fclose($fp);
               return true;
          }else{
                return true;
          }
     }else{
           return true;
     }
}
/**
 +------------------------------------------------------------------------
 * 转换提示信息编码
 +------------------------------------------------------------------------
 * @param    string  $srclang          源字符集
 * @param    string  $tarlang          目标字符集     
 * @param    string  $msginfo          要转换的信息文本
 +------------------------------------------------------------------------
 */
 function im_convert($srclang,$tarlang,$msginfo){  
      return $msginfo = siconv($msginfo, $tarlang, $srclang);
 }
/**
 +------------------------------------------------------------------------
 * 数据库查询前，对tplid进行安全性处理
 +------------------------------------------------------------------------
 * @param    string  $tplids      模板id组成字符串，不同id之间以逗号分隔
 +------------------------------------------------------------------------
 */
 function safe_tplid($tplids) {
      if(!$tplids){
           return false;
      }
      //验证是否为数字id
      $_tpl = explode(',',$tplids);
      $_tplids = '';
      foreach($_tpl as $_tid){
           if(is_numeric($_tid)){
                $_tplids =  $_tplids ? $_tplids.','.$_tid : $_tplids;
           }
      }
      if($_tplids){
           return $_tplids;
      }else{
           return false;
      }
 }
/**
 +------------------------------------------------------------------------
 * 修改接口文件或者header.htm文件中安装路径
 +------------------------------------------------------------------------
 * @param    string  $file      文件路径
 * @param    string  $type      文件类型，0：imxml.php文件；1：imconfig.inc.php文件
 +------------------------------------------------------------------------
 */ 
 function im_modify_root($file,$type=0){
      global $im_siteid, $im_sitekey;
      if(file_exists($file)){
           if($type==0){
                if(!defined("NTALKER_DATA_ROOT") && SHOW_INS_ROOT=='./ntalker/'){
                     return true;
                }else{
                     $filecontent = file_get_contents($file);
                     if(defined("NTALKER_DATA_ROOT") && file_exists(Uchome_ROOT.'./data/ntalker/imxml.php')){
                          $filecontent = preg_replace("/'SUB_DIR','\/ntalker\/'/i","'SUB_DIR', '/data/ntalker/'",$filecontent);
                     }else{
                          $sub_dir = substr(SHOW_INS_SITEURL, 0, 1) == '/' ? SHOW_INS_SITEURL : '/'.SHOW_INS_SITEURL;
                          $sub_dir = substr(SHOW_INS_SITEURL, -1, 1) == '/' ? $sub_dir : $sub_dir.'/';
                          $filecontent = preg_replace("/'SUB_DIR','\/ntalker\/'/i","'SUB_DIR', '$sub_dir'",$filecontent);
                     }
                }
           }else{
                $filecontent = file_get_contents($file);
                if(@preg_match('/\$im_siteid.*?=.*?(\"|\')(.*)?(\1).*?;/i', $filecontent, $matches) > 0){
                     $newsiteid = "\$im_siteid = \"".$im_siteid."\";";
                     $filecontent = preg_replace('/\$im_siteid.*?=.*?(\"|\')(.*)?(\1).*?;/i', $newsiteid, $filecontent); 
                } 
                if(@preg_match('/\$im_sitekey.*?=.*?(\"|\')(.*)?(\1).*?;/i', $filecontent, $matches) > 0){
                     $newsitekey = "\$im_sitekey = \"".$im_sitekey."\";";
                     $filecontent = preg_replace('/\$im_sitekey.*?=.*?(\"|\')(.*)?(\1).*?;/i', $newsitekey, $filecontent);
                }
           }
           if(!$fp=@fopen($file, "wb")){
                //message(false, '更新文件'.$file.'...失败，接口文件打开出错，如果在php.ini中配置了opendir，请修改配置；如果使用了php安全模式，请开启safe_mode_gid');
                return false;
           }
           if(!@fwrite($fp, $filecontent)){
                //message(false, '更新文件'.$file.'...失败，接口文件写入出错，请检查文件权限');
                return false;
           }
           if($fp) fclose($fp);
           return true;
      }else{
           return false;
      }
 }
/**
 +------------------------------------------------------------------------
 *  开通成功，开启ntalker 
 +------------------------------------------------------------------------
 * @param    string  $xmlfile      接口文件路径
 +------------------------------------------------------------------------
 */ 
 function open_ntalker($configfile){
      if(file_exists($configfile)){
           $filecontent = file_get_contents($configfile);
           $newsopen = '$im_enable = true;';
           $filecontent = preg_replace('/\$im_enable\s*?=.*?(true|false).*?;/i', $newsopen, $filecontent);
           $fp=@fopen($configfile, "wb");
           @fwrite($fp, $filecontent);
           fclose($fp);
      }
 }
?>